home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / UI101.ZIP / IO / UI / UI_ICON.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  31KB  |  1,364 lines

  1. /****************************************************************
  2.  
  3.     ui_icon.c       Icon-based Selection routines for
  4.             The Bywater Graphical User Interface
  5.  
  6.             Copyright (c) 1991, Ted A. Campbell
  7.  
  8.             Bywater Software
  9.             P. O. Box 4023 
  10.             Duke Station 
  11.             Durham, NC  27706
  12.  
  13.             email: tcamp@hercules.acpub.duke.edu
  14.  
  15.     Copyright and Permissions Information:
  16.  
  17.     All U.S. and international copyrights are claimed by the
  18.     author. The author grants permission to use this code
  19.     and software based on it under the following conditions:
  20.     (a) in general, the code and software based upon it may be 
  21.     used by individuals and by non-profit organizations; (b) it
  22.     may also be utilized by governmental agencies in any country,
  23.     with the exception of military agencies; (c) the code and/or
  24.     software based upon it may not be sold for a profit without
  25.     an explicit and specific permission from the author, except
  26.     that a minimal fee may be charged for media on which it is
  27.     copied, and for copying and handling; (d) the code must be 
  28.     distributed in the form in which it has been released by the
  29.     author; and (e) the code and software based upon it may not 
  30.     be used for illegal activities. 
  31.  
  32. ****************************************************************/
  33.  
  34. #include "stdio.h"
  35. #include "gr.h"
  36. #include "dr.h"
  37. #include "kb.h"
  38. #include "ui.h"
  39.  
  40. #define USESMALLFONT
  41. #define SMALLFONTSIZE   35
  42.  
  43. /****************************************************************
  44.  
  45.    ui_ficon()   File selection -- icon-based
  46.  
  47. ****************************************************************/
  48.  
  49. ui_ficon( x1, y1, x2, y2, specifier, title, m_box,
  50.    d_entries, max_entries,
  51.    background, foreground, highlight )
  52.    int x1, y1, x2, y2, background, foreground, highlight, max_entries;
  53.    struct menu_box *m_box;
  54.    char *specifier, *title;
  55.    struct dir_ent **d_entries;
  56.    {
  57.    register int c, test;
  58.    int carry_on, mo_xsrc, mo_ysrc;
  59.    static int x_pos, y_pos, b_stat, item;
  60.  
  61.    uii_draw( x1, y1, x2, y2, specifier, title, m_box,
  62.       d_entries, max_entries,
  63.       background, foreground, highlight );
  64.  
  65.    uii_activate( m_box, 0 );
  66.  
  67.    test = FALSE;
  68.    carry_on = TRUE;
  69.    while( carry_on == TRUE )
  70.       {
  71.       if ( kb_rxstat() == TRUE )
  72.      {
  73.      c = kb_rx();
  74.      test = TRUE;
  75.      }
  76.       else if ( gr_ismouse == TRUE )
  77.      {
  78.      if ( gr_mouse( SAMPLE, &x_pos, &y_pos, &b_stat )
  79.         == TRUE )
  80.         {
  81.         c = 0;
  82.         test = TRUE;
  83.         gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
  84.         mo_xsrc = x_pos;
  85.         mo_ysrc = y_pos;
  86.         gr_mouse( WAIT, &x_pos, &y_pos, &b_stat );
  87.         }
  88.      }
  89.  
  90.       if ( test == TRUE )
  91.      {
  92.      c = uii_event( m_box, c, mo_xsrc, mo_ysrc, x_pos, y_pos, &item );
  93.         switch( c )
  94.         {
  95.         case EVENT_SELECTED:
  96.            carry_on = FALSE;
  97.            break;
  98.         case EVENT_EXIT:
  99.            item = TK_EXIT;
  100.            carry_on = FALSE;
  101.            break;
  102.         case EVENT_ERROR:
  103.            bw_error( "Error return from uil_event()" );
  104.            carry_on = FALSE;
  105.            break;
  106.         case EVENT_NULL:
  107.         default:
  108.            test = FALSE;
  109.            break;
  110.         }
  111.      }
  112.  
  113.       ui_poll();
  114.  
  115.       }
  116.  
  117.    uii_deactivate( m_box );
  118.  
  119.    return item;
  120.  
  121.    }
  122.  
  123. /****************************************************************
  124.  
  125.     uii_draw()      - draw file selection icon area
  126.  
  127. ****************************************************************/
  128.  
  129. uii_draw( x1, y1, x2, y2, specifier, title, m_box,
  130.    d_entries, max_entries,
  131.    background, foreground, highlight )
  132.    int x1, y1, x2, y2, background, foreground, highlight, max_entries;
  133.    struct menu_box *m_box;
  134.    char *specifier, *title;
  135.    struct dir_ent **d_entries;
  136.    {
  137.    register int number, c;
  138.    int x, y;
  139.    int carry_on;
  140.  
  141. #ifdef  OLD_DEBUG
  142.    sprintf( ui_tbuf, "uii_draw(): %d %d %d %d", x1, y1, x2, y2 );
  143.    bw_debug( ui_tbuf );
  144.    sprintf( ui_tbuf, "uii_draw(): is_drawn = %d", m_box->is_drawn );
  145.    bw_debug( ui_tbuf );
  146. #endif
  147.  
  148.    /* First check for existence of the file */
  149.  
  150.    number = 0;
  151.    if ( dr_first( specifier, d_entries[ number ] ) == FALSE )
  152.       {
  153.       return TK_ERROR;
  154.       }
  155.  
  156.    /* Find all entries */
  157.  
  158.    number = 1;
  159.    while( ( dr_next( d_entries[ number ] ) == TRUE )
  160.       && ( number < max_entries ))
  161.       {
  162.       ++number;
  163.       }
  164.    m_box->number = number;
  165.  
  166.    /* the following are performed only if the window has not been
  167.       redrawn -- programmer may force redrawing of the whole menu
  168.       box by setting the is_drawn int to 0 (FALSE) */
  169.  
  170.    if ( m_box->is_drawn != TRUE )
  171.       {
  172.  
  173.       /* draw the menu window */
  174.  
  175.       if ( m_box->window == NULL )
  176.          {
  177.  
  178. #ifdef  OLD_DEBUG
  179.    sprintf( ui_tbuf, "uii_draw(): ready to draw window" );
  180.    bw_debug( ui_tbuf );
  181. #endif
  182.  
  183.      m_box->window = ui_window( x1, y1, x2, y2,
  184.             TRUE, highlight, foreground,
  185.             title, TRUE, BLACK,
  186.         FALSE, BLACK, background, SOLID,
  187.         BUT_CLOSE | BUT_MOVE | BUT_RESIZE );
  188.          }
  189.       else
  190.          {
  191.  
  192. #ifdef  OLD_DEBUG
  193.    sprintf( ui_tbuf, "uii_draw(): redraw window" );
  194.    bw_debug( ui_tbuf );
  195. #endif
  196.  
  197.      ui_rewindow( m_box->window, title );
  198.          }
  199.       }
  200.  
  201.    /* on the other hand, if the menu box is not to be redrawn,
  202.       it should in any case be retitled */
  203.  
  204.    else
  205.       {
  206.       ui_wtitle( m_box->window, title );
  207.       }
  208.  
  209. #ifdef  OLD_DEBUG
  210.    sprintf( ui_tbuf, "uii_draw() found %d entries", m_box->number );
  211.    bw_debug( ui_tbuf );
  212. #endif
  213.  
  214.    /* save font style and size, then attempt to set small font */
  215.  
  216. #ifdef  USESMALLFONT
  217.    m_box->save_font = ui_grwind->font;
  218.    m_box->save_fysize = ui_grwind->fysize;
  219.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  220. #endif
  221.  
  222. #ifdef OLD_DEBUG
  223.    sprintf( ui_tbuf, "uii_draw(): font_set" );
  224.    bw_debug( ui_tbuf );
  225. #endif
  226.  
  227.    /* assign colors to structure */
  228.  
  229.    m_box->fore = foreground;
  230.    m_box->back = background;
  231.    m_box->high = highlight;
  232.  
  233.    /* save d_titles */
  234.  
  235.    m_box->d_entries = d_entries;
  236.    m_box->max_entries = max_entries;
  237.    m_box->type = MENU_ICON;
  238.  
  239.    /* calculate icon size */
  240.  
  241.    m_box->xsize = gr_strlen( "123456789012345" );
  242.    m_box->ysize = ui_grwind->fysize * 4;
  243.  
  244. #ifdef  OLD_DEBUG
  245.    sprintf( ui_tbuf, "ui_ficon(): icon size calculated" );
  246.    bw_debug( ui_tbuf );
  247. #endif
  248.  
  249.    /* the sliders have to be redrawn only if the is_drawn int
  250.       is 0 (FALSE) */
  251.  
  252.    if ( m_box->is_drawn != TRUE )
  253.       {
  254.       uil_sliders( m_box );
  255.       }
  256.  
  257. #ifdef  OLD_DEBUG
  258.    sprintf( ui_tbuf, "ui_ficon(): sliders drawn" );
  259.    bw_debug( ui_tbuf );
  260. #endif
  261.  
  262.    /* abort if a single icon will not fit */
  263.  
  264.    if ( ( m_box->i_x2 - m_box->i_x1 ) < m_box->xsize )
  265.       {
  266. #ifdef  USESMALLFONT
  267.    gr_font( ui_screen, m_box->save_font,
  268.       m_box->save_fysize );
  269. #endif
  270.       return TK_ERROR;
  271.       }
  272.  
  273.    if ( ( m_box->i_y2 - m_box->i_y1 ) < m_box->ysize )
  274.       {
  275. #ifdef  USESMALLFONT
  276.    gr_font( ui_screen, m_box->save_font,
  277.       m_box->save_fysize );
  278. #endif
  279.       return TK_ERROR;
  280.       }
  281.  
  282.    /* calculate total number of icon spaces */
  283.  
  284.    m_box->x_items = m_box->x_logical =
  285.       ( m_box->i_x2 - m_box->i_x1 ) / m_box->xsize;
  286.    m_box->y_items =
  287.       ( m_box->i_y2 - m_box->i_y1 ) / m_box->ysize;
  288.  
  289.    /* set roughly equal x and y items if all cannot be shown */
  290.  
  291.    if ( ( m_box->x_items * m_box->y_items ) < m_box->number )
  292.       {
  293.       for ( x = m_box->x_items + 2; (x * x) < m_box->number; ++x )
  294.          {
  295.          }
  296.       --x;
  297.       m_box->x_logical = x;
  298.       }
  299.  
  300.    m_box->y_logical = m_box->number / m_box->x_logical;
  301.    if (( m_box->number % m_box->x_logical ) > 0 )
  302.       {
  303.       ++m_box->y_logical;
  304.       }
  305.  
  306. #ifdef  OLD_DEBUG
  307.    sprintf( ui_tbuf, "ui_ficon() point 2" );
  308.    bw_debug( ui_tbuf );
  309. #endif
  310.  
  311.    /* calculate increments for elevators */
  312.  
  313.    x = ui_grwind->ymax / 15;
  314.    y = ( x * gr_pxsize ) / gr_pysize;
  315.  
  316.    if ( m_box->y_logical <= m_box->y_items )
  317.       {
  318.       m_box->vel_inc = 1;
  319.       }
  320.    else
  321.       {
  322.       m_box->vel_inc = ((( m_box->ve_y2 - ( m_box->ve_y1 + y ))
  323.          * INC_ACCURACY )
  324.          / ( m_box->y_logical - m_box->y_items ));
  325.       }
  326.  
  327.    if ( m_box->x_logical <= m_box->x_items )
  328.       {
  329.       m_box->hel_inc = 1;
  330.       }
  331.    else
  332.       {
  333.       m_box->hel_inc = ((( m_box->he_x2 - ( m_box->he_x1 + x ))
  334.          * INC_ACCURACY )
  335.          / ( m_box->x_logical - m_box->x_items ));
  336.       }
  337.  
  338. #ifdef  OLD_DEBUG
  339.    sprintf( ui_tbuf, "window:  x1 = %d, y1 = %d, x2 = %d, y2 = %d, \nicon_xsize = %d, icon_ysize = %d, number = %d, x_items = %d, y_items = %d",
  340.       m_box->i_x1, m_box->i_y1, m_box->i_x2,
  341.       m_box->i_y2,
  342.       m_box->xsize, m_box->ysize, number, m_box->x_items, m_box->y_items );
  343.    bw_debug( ui_tbuf );
  344.    sprintf( ui_tbuf, "ui_ficon() point 3" );
  345.    bw_debug( ui_tbuf );
  346. #endif
  347.  
  348.    /* set initial values */
  349.  
  350.    m_box->current = m_box->x_start 
  351.       = m_box->y_start = m_box->x_pos = m_box->y_pos = 0;
  352.  
  353.    /* Display each icon */
  354.  
  355.    uii_display( m_box );
  356.  
  357.    /* note that the menu box is now drawn */
  358.  
  359.    m_box->is_drawn = TRUE;
  360.  
  361. #ifdef  USESMALLFONT
  362.    gr_font( ui_screen, m_box->save_font,
  363.       m_box->save_fysize );
  364. #endif
  365.  
  366. /*   uil_exit( m_box ); */
  367.  
  368.    }
  369.  
  370. /****************************************************************
  371.  
  372.    uii_activate()   Activate an icon menu box
  373.  
  374. ****************************************************************/
  375.  
  376. uii_activate( m_box, item )
  377.    struct menu_box *m_box;
  378.    int item;
  379.    {
  380.    register int x, y;
  381.    int carry_on;
  382.    
  383. #ifdef  OLD_DEBUG
  384.    if ( m_box->d_entries == NULL )
  385.       {
  386.       bw_error( "Programmer error: menu box has not been drawn!" );
  387.       return FALSE;
  388.       }
  389. #endif
  390.  
  391. #ifdef  USESMALLFONT
  392.    m_box->save_font = ui_grwind->font;
  393.    m_box->save_fysize = ui_grwind->fysize;
  394.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  395. #endif
  396.  
  397.    if ( item > m_box->number )
  398.       {
  399.       item = 0;
  400.       }
  401.  
  402.    if ( item == 0 )
  403.       {
  404.       m_box->x_start = m_box->y_start = m_box->x_pos = m_box->y_pos
  405.          = m_box->current = 0;
  406.       }
  407.    else if ( item != m_box->current )
  408.       {
  409.  
  410.       m_box->current = item;
  411.       
  412.       /* calculate y_start */
  413.  
  414.       y = 0;
  415.       carry_on = TRUE;
  416.       if ( m_box->y_logical <= m_box->y_items )
  417.          {
  418.          y = 0;
  419.          }
  420.       else while( ( y < m_box->y_logical ) && ( carry_on == TRUE ))
  421.          {
  422.          if ( (( m_box->x_logical * y ) +
  423.             ( m_box->x_logical * m_box->y_items )) > item )
  424.             {
  425.             carry_on = FALSE;
  426.             }
  427.          else
  428.             {
  429.             ++y;
  430.             }
  431.          }
  432.  
  433.       /* calculate x_start */
  434.  
  435.       x = 0;
  436.       carry_on = TRUE;
  437.       if ( m_box->x_logical <= m_box->x_items )
  438.          {
  439.          x = 0;
  440.  
  441. #ifdef OLD_DEBUG
  442.       sprintf( ui_tbuf, "x_logical <= x_items" );
  443.       ui_wtitle( m_box->window, ui_tbuf );
  444.       ui_wait();
  445. #endif
  446.          }
  447.       else while( ( x < m_box->x_logical ) && ( carry_on == TRUE ))
  448.          {
  449.  
  450. #ifdef OLD_DEBUG
  451.       sprintf( ui_tbuf, "item <> x_logical = %d",  item % m_box->x_logical );
  452.       ui_wtitle( m_box->window, ui_tbuf );
  453.       ui_wait();
  454.       
  455.       sprintf( ui_tbuf, "trying %d", x );
  456.       ui_wtitle( m_box->window, ui_tbuf );
  457.       ui_wait();
  458. #endif
  459.  
  460.          if (( m_box->x_items + x ) > ( item % m_box->x_logical ))
  461.             {
  462.             carry_on = FALSE;
  463.             }
  464.          else
  465.             {
  466.             ++x;
  467.             }
  468.          }
  469.  
  470. #ifdef OLD_DEBUG
  471.       sprintf( ui_tbuf, "i %d; x %d; y %d", item, x, y );
  472.       ui_wtitle( m_box->window, ui_tbuf );
  473. #endif
  474.  
  475.       m_box->y_start = y;
  476.       m_box->x_start = x;
  477.       m_box->y_pos = ( item / m_box->x_logical ) - m_box->y_start;
  478.       m_box->x_pos = ( item % m_box->x_logical ) - m_box->x_start;
  479.  
  480.       uii_display( m_box );
  481.       }
  482.  
  483.    /* show current item selected */
  484.  
  485.    uii_icon( m_box, m_box->current, TRUE );
  486.  
  487. #ifdef  USESMALLFONT
  488.    gr_font( ui_screen, m_box->save_font,
  489.       m_box->save_fysize );
  490. #endif
  491.  
  492.    }
  493.  
  494. /****************************************************************
  495.  
  496.    uii_deactivate()   Deactivate an icon menu box
  497.  
  498. ****************************************************************/
  499.  
  500. uii_deactivate( m_box )
  501.    struct menu_box *m_box;
  502.    {
  503.  
  504. #ifdef  USESMALLFONT
  505.    m_box->save_font = ui_grwind->font;
  506.    m_box->save_fysize = ui_grwind->fysize;
  507.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  508. #endif
  509.  
  510.    uii_icon( m_box, m_box->current, FALSE );
  511.  
  512. #ifdef  USESMALLFONT
  513.    gr_font( ui_screen, m_box->save_font,
  514.       m_box->save_fysize );
  515. #endif
  516.  
  517.    }
  518.  
  519. /****************************************************************
  520.  
  521.    uii_event()   Query if keyboard or mouse actions affect an icon
  522.                 menu box
  523.  
  524. ****************************************************************/
  525.  
  526. uii_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, item )
  527.    struct menu_box *m_box;
  528.    int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest;
  529.    int *item;
  530.    {
  531.    static int how_far, x_sel, y_sel;
  532.    int carry_on;
  533.    register int c;
  534.  
  535.    how_far = 0;
  536.    x_sel = 0;
  537.    y_sel = 0;
  538.    c = ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
  539.       &how_far, &x_sel, &y_sel );
  540.  
  541.    switch( c )
  542.       {
  543.  
  544.       case CR:
  545.       case LF:
  546.          *item = m_box->current;
  547.          return EVENT_SELECTED;
  548.      break;
  549.  
  550.       case ESCAPE:
  551.       case TK_EXIT:
  552.       case MO_EXIT:
  553.      *item = m_box->current = TK_EXIT;
  554.          return EVENT_EXIT;
  555.      break;
  556.  
  557.       case KB_DOWN:
  558.  
  559.      /* First test to see if it is possible to move
  560.         down one line on the y axis */
  561.  
  562.      if ( m_box->current <
  563.         ( m_box->number - m_box->x_logical ))
  564.         {
  565.  
  566. #ifdef  USESMALLFONT
  567.    m_box->save_font = ui_grwind->font;
  568.    m_box->save_fysize = ui_grwind->fysize;
  569.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  570. #endif
  571.  
  572.         /* show current item unselected */
  573.  
  574.         uii_icon( m_box, m_box->current, FALSE );
  575.  
  576.         /* advance current item and m_box->y_pos */
  577.  
  578.         m_box->current += m_box->x_logical;
  579.         ++m_box->y_pos;
  580.  
  581.         /* check to see if this will advance
  582.            past the visible lines in the icon
  583.            area */
  584.  
  585.         if ( m_box->y_pos == m_box->y_items )
  586.            {
  587.            ++m_box->y_start;
  588.            --m_box->y_pos;
  589.            uii_display( m_box );
  590.            }
  591.  
  592.         /* show current item selected */
  593.  
  594.         uii_icon( m_box, m_box->current, TRUE );
  595.  
  596.  
  597. #ifdef  USESMALLFONT
  598.    gr_font( ui_screen, m_box->save_font,
  599.       m_box->save_fysize );
  600. #endif
  601.  
  602.         }
  603.  
  604.      *item = m_box->current;
  605.      return EVENT_CHANGE;
  606.      break;
  607.  
  608.       case KB_UP:
  609.  
  610.      /* First test to see if it is possible to move
  611.         up one line on the y axis */
  612.  
  613.      if ( m_box->current >=  m_box->x_logical )
  614.         {
  615.  
  616. #ifdef  USESMALLFONT
  617.    m_box->save_font = ui_grwind->font;
  618.    m_box->save_fysize = ui_grwind->fysize;
  619.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  620. #endif
  621.  
  622.         /* show current item unselected */
  623.  
  624.         uii_icon( m_box, m_box->current, FALSE );
  625.  
  626.         /* decrement current item and m_box->y_pos */
  627.  
  628.         m_box->current -= m_box->x_logical;
  629.         --m_box->y_pos;
  630.  
  631.         /* check to see if this will decrement
  632.            past the visible lines in the icon
  633.            area */
  634.  
  635.         if ( m_box->y_pos < 0 )
  636.            {
  637.            --m_box->y_start;
  638.            ++m_box->y_pos;
  639.            uii_display( m_box );
  640.            }
  641.  
  642.         /* show current item selected */
  643.  
  644.         uii_icon( m_box, m_box->current, TRUE );
  645.  
  646. #ifdef  USESMALLFONT
  647.    gr_font( ui_screen, m_box->save_font,
  648.       m_box->save_fysize );
  649. #endif
  650.  
  651.         }
  652.  
  653.      *item = m_box->current;
  654.      return EVENT_CHANGE;
  655.      break;
  656.  
  657.       case KB_LEFT:
  658.  
  659.      /* First test to see if it is possible to move
  660.         left one column on the x axis */
  661.  
  662.      if ( ( m_box->current % m_box->x_logical ) > 0 )
  663.         {
  664.  
  665. #ifdef  USESMALLFONT
  666.    m_box->save_font = ui_grwind->font;
  667.    m_box->save_fysize = ui_grwind->fysize;
  668.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  669. #endif
  670.  
  671.         /* show current item unselected */
  672.  
  673.         uii_icon( m_box, m_box->current, FALSE );
  674.  
  675.         /* decrement current item and m_box->x_pos */
  676.  
  677.         --m_box->current;
  678.         --m_box->x_pos;
  679.  
  680.         /* check to see if this will decrement
  681.            past the visible lines in the icon
  682.            area */
  683.  
  684.         if ( m_box->x_pos < 0 )
  685.            {
  686.            --m_box->x_start;
  687.            ++m_box->x_pos;
  688.            uii_display( m_box );
  689.            }
  690.  
  691.         /* show current item selected */
  692.  
  693.         uii_icon( m_box, m_box->current, TRUE );
  694.  
  695.  
  696. #ifdef  USESMALLFONT
  697.    gr_font( ui_screen, m_box->save_font,
  698.       m_box->save_fysize );
  699. #endif
  700.  
  701.         }
  702.  
  703.      *item = m_box->current;
  704.      return EVENT_CHANGE;
  705.      break;
  706.  
  707.       case KB_RIGHT:
  708.  
  709.      /* First test to see if it is possible to move
  710.         right one column on the x axis */
  711.  
  712.      if ( (( m_box->current % m_box->x_logical ) <
  713.         ( m_box->x_logical - 1 )) &&
  714.         ( m_box->current < ( m_box->number-1 ) ))
  715.         {
  716.  
  717. #ifdef  USESMALLFONT
  718.    m_box->save_font = ui_grwind->font;
  719.    m_box->save_fysize = ui_grwind->fysize;
  720.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  721. #endif
  722.  
  723.         /* show current item unselected */
  724.  
  725.         uii_icon( m_box, m_box->current,
  726.            FALSE );
  727.  
  728.         /* increment current item and m_box->x_pos */
  729.  
  730.         ++m_box->current;
  731.         ++m_box->x_pos;
  732.  
  733.         /* check to see if this will increment
  734.            past the visible lines in the icon
  735.            area */
  736.  
  737.         if ( m_box->x_pos >= m_box->x_items )
  738.            {
  739.            ++m_box->x_start;
  740.            --m_box->x_pos;
  741.            uii_display( m_box );
  742.            }
  743.  
  744.         /* show current item selected */
  745.  
  746.         uii_icon( m_box, m_box->current,
  747.            TRUE );
  748.  
  749.  
  750. #ifdef  USESMALLFONT
  751.    gr_font( ui_screen, m_box->save_font,
  752.       m_box->save_fysize );
  753. #endif
  754.  
  755.         }
  756.  
  757.      *item = m_box->current;
  758.      return EVENT_CHANGE;
  759.      break;
  760.  
  761.       case MO_UP:
  762.  
  763.      /* first see if it is possible to move up
  764.         at all */
  765.  
  766.      if (( m_box->y_start > 0 ) && ( how_far > 0 ))
  767.         {
  768.  
  769. #ifdef  USESMALLFONT
  770.    m_box->save_font = ui_grwind->font;
  771.    m_box->save_fysize = ui_grwind->fysize;
  772.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  773. #endif
  774.  
  775.         /* decrement how_far to an acceptable
  776.            number */
  777.  
  778.         while ( ( m_box->y_start - how_far ) < 0 )
  779.            {
  780.            --how_far;
  781.            }
  782.  
  783.         /* assign new values to m_box->y_start and
  784.            m_box->current */
  785.  
  786.         m_box->y_start -= how_far;
  787.         m_box->current -= how_far * m_box->x_logical;
  788.  
  789.         /* display all icons visible */
  790.  
  791.         uii_display( m_box );
  792.  
  793.         /* display currently selected icon */
  794.  
  795.         uii_icon( m_box, m_box->current,
  796.            TRUE );
  797.  
  798.  
  799. #ifdef  USESMALLFONT
  800.    gr_font( ui_screen, m_box->save_font,
  801.       m_box->save_fysize );
  802. #endif
  803.  
  804.         }
  805.  
  806.      *item = m_box->current;
  807.      return EVENT_CHANGE;
  808.      break;
  809.  
  810.       case MO_DN:
  811.  
  812.      /* first see if it is possible to move down
  813.         at all */
  814.  
  815.      if (( m_box->y_start <
  816.         ( m_box->y_logical - m_box->y_items ) )
  817.         && ( how_far > 0 ))
  818.         {
  819.  
  820. #ifdef  USESMALLFONT
  821.    m_box->save_font = ui_grwind->font;
  822.    m_box->save_fysize = ui_grwind->fysize;
  823.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  824. #endif
  825.  
  826.         /* increment how_far to an acceptable
  827.            number */
  828.  
  829.         while ( ( m_box->y_start + how_far ) >
  830.            ( m_box->y_logical
  831.            - m_box->y_items ))
  832.            {
  833.            --how_far;
  834.            }
  835.  
  836.         /* assign new values to m_box->y_start and
  837.            m_box->current */
  838.  
  839.         m_box->y_start += how_far;
  840.         m_box->current += how_far * m_box->x_logical;
  841.  
  842.         /* display all icons visible */
  843.  
  844.         uii_display( m_box );
  845.  
  846.         /* display currently selected icon */
  847.  
  848.         uii_icon( m_box, m_box->current,
  849.            TRUE );
  850.  
  851.  
  852. #ifdef  USESMALLFONT
  853.    gr_font( ui_screen, m_box->save_font,
  854.       m_box->save_fysize );
  855. #endif
  856.  
  857.         }
  858.  
  859.      *item = m_box->current;
  860.      return EVENT_CHANGE;
  861.      break;
  862.  
  863.       case MO_RIGHT:
  864.  
  865.      /* first see if it is possible to move right
  866.         at all */
  867.  
  868.      if (( m_box->x_start <
  869.         ( m_box->x_logical - m_box->x_items ) )
  870.         && ( how_far > 0 ))
  871.         {
  872.  
  873. #ifdef  USESMALLFONT
  874.    m_box->save_font = ui_grwind->font;
  875.    m_box->save_fysize = ui_grwind->fysize;
  876.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  877. #endif
  878.  
  879.         /* increment how_far to an acceptable
  880.            number */
  881.  
  882.         while ( ( m_box->x_start + how_far ) >
  883.            ( m_box->x_logical
  884.            - m_box->x_items ))
  885.            {
  886.            --how_far;
  887.            }
  888.  
  889.         /* assign new values to m_box->x_start and
  890.            m_box->current */
  891.  
  892.         m_box->x_start += how_far;
  893.             m_box->current += how_far;
  894.  
  895.             /* display all icons visible */
  896.  
  897.         uii_display( m_box );
  898.  
  899.             /* display currently selected icon */
  900.  
  901.         uii_icon( m_box, m_box->current,
  902.                TRUE );
  903.  
  904.  
  905. #ifdef  USESMALLFONT
  906.    gr_font( ui_screen, m_box->save_font,
  907.       m_box->save_fysize );
  908. #endif
  909.  
  910.             }
  911.  
  912.      *item = m_box->current;
  913.      return EVENT_CHANGE;
  914.          break;
  915.  
  916.       case MO_LEFT:
  917.  
  918.          /* first see if it is possible to move left
  919.             at all */
  920.  
  921.          if (( m_box->x_start > 0 ) && ( how_far > 0 ))
  922.             {
  923.  
  924. #ifdef  USESMALLFONT
  925.    m_box->save_font = ui_grwind->font;
  926.    m_box->save_fysize = ui_grwind->fysize;
  927.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  928. #endif
  929.  
  930.             /* decrement how_far to an acceptable
  931.                number */
  932.  
  933.             while ( ( m_box->x_start - how_far ) < 0 )
  934.                {
  935.                --how_far;
  936.                }
  937.  
  938.             /* assign new values to m_box->x_start and
  939.                m_box->current */
  940.  
  941.             m_box->x_start -= how_far;
  942.             m_box->current -= how_far;
  943.  
  944.             /* display all icons visible */
  945.  
  946.         uii_display( m_box );
  947.  
  948.             /* display currently selected icon */
  949.  
  950.         uii_icon( m_box, m_box->current,
  951.                TRUE );
  952.  
  953.  
  954. #ifdef  USESMALLFONT
  955.    gr_font( ui_screen, m_box->save_font,
  956.       m_box->save_fysize );
  957. #endif
  958.  
  959.             }
  960.  
  961.      *item = m_box->current;
  962.      return EVENT_CHANGE;
  963.          break;
  964.  
  965.       case MO_SEL:
  966.          if ( ((( y_sel + m_box->y_start ) * m_box->x_logical )
  967.             + x_sel + m_box->x_start ) == m_box->current )
  968.             {
  969.             *item = m_box->current;
  970.             return EVENT_SELECTED;
  971.             }
  972.          else
  973.             {
  974.  
  975. #ifdef  USESMALLFONT
  976.    m_box->save_font = ui_grwind->font;
  977.    m_box->save_fysize = ui_grwind->fysize;
  978.    gr_font( ui_screen, F_DEFAULT, ui_grwind->ymax / SMALLFONTSIZE );
  979. #endif
  980.  
  981.         uii_icon( m_box, m_box->current, FALSE );
  982.             m_box->current = (( y_sel + m_box->y_start )
  983.                * m_box->x_logical )
  984.                + m_box->x_start + x_sel;
  985.             m_box->x_pos = x_sel;
  986.             m_box->y_pos = y_sel;
  987.         uii_icon( m_box, m_box->current, TRUE );
  988.  
  989. #ifdef  USESMALLFONT
  990.    gr_font( ui_screen, m_box->save_font,
  991.       m_box->save_fysize );
  992. #endif
  993.  
  994.             }
  995.      *item = m_box->current;
  996.      return EVENT_CHANGE;
  997.          break;
  998.  
  999.       case MO_SRC:
  1000.  
  1001.           *item = (( y_sel + m_box->y_start ) * m_box->x_logical )
  1002.                + m_box->x_start + x_sel;
  1003.          return EVENT_SOURCE;
  1004.          break;
  1005.  
  1006.       default:
  1007.          *item = 0;
  1008.          return EVENT_NULL;
  1009.          break;
  1010.  
  1011.       }
  1012.    }
  1013.  
  1014. /****************************************************************
  1015.  
  1016.    uii_source()   Query if keyboard or mouse actions indicate a
  1017.           source within a menu box
  1018.  
  1019. ****************************************************************/
  1020.  
  1021. uii_source( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest, item )
  1022.    struct menu_box *m_box;
  1023.    int key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest;
  1024.    int *item;
  1025.    {
  1026.    static int how_far, x_sel, y_sel;
  1027.    int carry_on;
  1028.    register int c;
  1029.  
  1030.    how_far = 0;
  1031.    x_sel = 0;
  1032.    y_sel = 0;
  1033.    c = ui_event( m_box, key, mo_xsrc, mo_ysrc, mo_xdest, mo_ydest,
  1034.       &how_far, &x_sel, &y_sel );
  1035.  
  1036.    if ( c == MO_SRC )
  1037.       {
  1038.       *item = (( y_sel + m_box->y_start ) * m_box->x_logical )
  1039.      + m_box->x_start + x_sel;
  1040.       return TRUE;
  1041.       }
  1042.    else
  1043.       {
  1044.       return FALSE;
  1045.       }
  1046.    }
  1047.  
  1048. /****************************************************************
  1049.  
  1050.    uii_display()      Show all file icons
  1051.  
  1052. ****************************************************************/
  1053.  
  1054. uii_display( m_box )
  1055.    struct menu_box *m_box;
  1056.    {
  1057.    register int c;
  1058.  
  1059.    /* blank the entire icon area */
  1060.  
  1061.    ui_fbox( m_box->i_x1, m_box->i_y1, m_box->i_x2, m_box->i_y2,
  1062.       m_box->back, SOLID );
  1063.  
  1064.    /* attempt to show each icon */
  1065.  
  1066.    for ( c = 0; c < m_box->number; ++c )
  1067.       {
  1068.       uii_icon( m_box, c,
  1069.          FALSE );
  1070.       }
  1071.  
  1072.    /* show elevators */
  1073.  
  1074.    uil_vel( m_box, m_box->y_start );            /* show vertical elevator */
  1075.    uil_hel( m_box, m_box->x_start );            /* show horizontal elevator */
  1076.  
  1077.    }
  1078.  
  1079. /****************************************************************
  1080.  
  1081.    uii_icon()   Draw file icon
  1082.  
  1083. ****************************************************************/
  1084.  
  1085. uii_icon( m_box, n, selected )
  1086.    int n, selected;
  1087.    struct menu_box *m_box;
  1088.    {
  1089.    register int x, y;
  1090.    int x1, y1, x2, y2, textxpos;
  1091.    int restore_clip, clx1, cly1, clx2, cly2;
  1092.    static char buf[ 20 ];
  1093.  
  1094. #ifdef  OLD_DEBUG
  1095.    sprintf( ui_tbuf, "uii_icon() called; item %d ", n );
  1096.    ui_wtitle( m_box->window, ui_tbuf );
  1097.    ui_wait();
  1098. #endif
  1099.  
  1100.    x = ( n % m_box->x_logical ) - m_box->x_start;
  1101.    y = ( n / m_box->x_logical ) - m_box->y_start;
  1102.  
  1103. #ifdef  OLD_DEBUG
  1104.    sprintf( ui_tbuf, "x = %d, y = %d", x, y );
  1105.    ui_text( m_box->i_x1, m_box->i_y1, m_box->i_x2,
  1106.       m_box->i_y2, 35, m_box->back, m_box->fore, ui_tbuf );
  1107.    ui_wait();
  1108. #endif
  1109.  
  1110.    if ( ( x < 0 ) || ( y < 0 ))
  1111.       {
  1112.       return FALSE;
  1113.       }
  1114.  
  1115.    if ( ( x >= ( m_box->x_items + gr_clipping ))
  1116.       || ( y >= ( m_box->y_items + gr_clipping )))
  1117.       {
  1118.       return FALSE;
  1119.       }
  1120.  
  1121.    x1 = m_box->i_x1 + ( x * m_box->xsize );
  1122.    y1 = m_box->i_y2 - ( ( 1 + y ) * m_box->ysize ) - 1;
  1123.    x2 = m_box->i_x1 + ( ( 1 + x ) * m_box->xsize ) - 1;
  1124.    y2 = m_box->i_y2 - ( y * m_box->ysize );
  1125.  
  1126.    /* see if cliiping is in effect */
  1127.  
  1128.    if ( ( gr_clipping == TRUE ) && ( ui_grwind->clipping == TRUE ))
  1129.       {
  1130.       restore_clip = TRUE;
  1131.       clx1 = ui_grwind->cl_x1;
  1132.       cly1 = ui_grwind->cl_y1;
  1133.       clx2 = ui_grwind->cl_x2;
  1134.       cly2 = ui_grwind->cl_y2;
  1135.       }
  1136.    else
  1137.       {
  1138.       restore_clip = FALSE;
  1139.       }
  1140.  
  1141.    if ( gr_clipping == TRUE )
  1142.       {
  1143.       gr_clip( ui_screen, TRUE, m_box->i_x1, m_box->i_y1,
  1144.          m_box->i_x2, m_box->i_y2 );
  1145.       }
  1146.  
  1147.    /* blank the icon area */
  1148.  
  1149.    ui_fbox( x1, y1, x2, y2, m_box->back, SOLID );
  1150.  
  1151.    /* add two blanks if the name is small */
  1152.  
  1153.    if ( strlen( m_box->d_entries[ n ]->filename ) < 6 )
  1154.       {
  1155.       sprintf( buf, " %s ", m_box->d_entries[ n ]->filename );
  1156.       }
  1157.    else
  1158.       {
  1159.       strcpy( buf, m_box->d_entries[ n ]->filename );
  1160.       }
  1161.  
  1162.    /* calculate centered text position */
  1163.  
  1164.    textxpos = ( x1 + ( m_box->xsize / 2 ))
  1165.       - ( gr_strlen( buf ) / 2 );
  1166.  
  1167.    /* print the text */
  1168.  
  1169.    if ( selected == TRUE )
  1170.       {
  1171.       gr_text( ui_screen, textxpos, y1 + 2,
  1172.           buf, m_box->back, m_box->fore );
  1173.       }
  1174.    else
  1175.       {
  1176.       gr_text( ui_screen, textxpos, y1 + 2,
  1177.          buf, m_box->fore, m_box->back );
  1178.       }
  1179.  
  1180.    /* increment y1 out of text area */
  1181.  
  1182.    y1 += ui_grwind->fysize;
  1183.  
  1184.    /* draw the icon */
  1185.  
  1186.    switch( m_box->d_entries[ n ]->type )
  1187.       {
  1188.  
  1189.       case    FILE_DIRECTORY:
  1190.      uii_folder( x1, y1, x2, y2, m_box->fore );
  1191.          break;
  1192.  
  1193.       case    FILE_EXECUTABLE:
  1194.      uii_exec( x1, y1, x2, y2, m_box->fore );
  1195.          break;
  1196.  
  1197.       case    FILE_NORMAL:
  1198.       default:
  1199.      uii_default( x1, y1, x2, y2, m_box->fore );
  1200.          break;
  1201.       }
  1202.  
  1203.    /* restore clipping or turn off clipping */
  1204.  
  1205.    if ( restore_clip == TRUE )
  1206.       {
  1207.       gr_clip( ui_screen, TRUE, clx1, cly1, clx2, cly2 );
  1208.       }
  1209.    else if ( gr_clipping == TRUE )
  1210.       {
  1211.       gr_clip( ui_screen, FALSE, 0, 0, 0, 0 );
  1212.       }
  1213.    }
  1214.  
  1215. /****************************************************************
  1216.  
  1217.    uii_default()   Default (blank or generic) file icon
  1218.  
  1219. ****************************************************************/
  1220.  
  1221. uii_default( x1, y1, x2, y2, color )
  1222.    int x1, y1, x2, y2, color;
  1223.    {
  1224. #ifdef USE_ICONS
  1225.    ui_pbmcenter( ui_screen, x1, y1, x2, y2, &ui_deficon );
  1226. #else
  1227.    int x, y, y_center, x_center;
  1228.  
  1229.    /* calculate the center of the icon area */
  1230.  
  1231.    y_center = y1 + (( y2 - y1 ) / 2 );
  1232.    x_center = x1 + (( x2 - x1 ) / 2 );
  1233.  
  1234.    /* calculate appropriate sizes for the icon */
  1235.  
  1236.    y = ( y2 - y1 ) / 3;
  1237.    x = ((( y * gr_pysize ) / gr_pxsize ) * 3 ) / 4;
  1238.  
  1239.    /* draw the icon rectangle */
  1240.  
  1241.    gr_rectangle( ui_screen, x_center - x,
  1242.       y_center - y,
  1243.       x_center + x,
  1244.       y_center + y, color, HOLLOW );
  1245.  
  1246.    /* draw demarking line across the top */
  1247.  
  1248.    gr_line( ui_screen, x_center - x, ( y_center + y ) - 3,
  1249.       x_center + x, ( y_center + y ) - 3, color, SOLID );
  1250.  
  1251. #endif
  1252.  
  1253.    }
  1254.  
  1255. /****************************************************************
  1256.  
  1257.    uii_folder()    File folder (directory) icon
  1258.  
  1259. ****************************************************************/
  1260.  
  1261. uii_folder( x1, y1, x2, y2, color )
  1262.    int x1, y1, x2, y2, color;
  1263.    {
  1264. #ifdef USE_ICONS
  1265.    ui_pbmcenter( ui_screen, x1, y1, x2, y2, &ui_foldicon );
  1266. #else
  1267.    int x, y, y_center, x_center;
  1268.  
  1269.    /* calculate the center of the icon area */
  1270.  
  1271.    y_center = y1 + (( y2 - y1 ) / 2 );
  1272.    x_center = x1 + (( x2 - x1 ) / 2 );
  1273.  
  1274.    /* calculate appropriate sizes for the folder */
  1275.  
  1276.    y = ( y2 - y1 ) / 4;
  1277.    x = ((( y * gr_pysize ) / gr_pxsize ) * 3 ) / 2;
  1278.  
  1279.    /* draw left side of folder */
  1280.  
  1281.    gr_line( ui_screen, x_center - x, y_center - y,
  1282.       x_center - x, y_center + y, color, SOLID );
  1283.  
  1284.    /* draw bottom of folder */
  1285.  
  1286.    gr_line( ui_screen, x_center - x, y_center - y,
  1287.       x_center + x, y_center - y, color, SOLID );
  1288.  
  1289.    /* draw right side of folder */
  1290.  
  1291.    gr_line( ui_screen, x_center + x, y_center - y,
  1292.       x_center + x, y_center + y, color, SOLID );
  1293.  
  1294.    /* draw file tab (upper) */
  1295.  
  1296.    gr_line( ui_screen, x_center + x, y_center + y,
  1297.       x_center + x - 4, y_center + y + 2, color, SOLID );
  1298.    gr_line( ui_screen, x_center + x - 4, y_center + y + 2,
  1299.       x_center + 4, y_center + y + 2, color, SOLID );
  1300.    gr_line( ui_screen, x_center + 4, y_center + y + 2,
  1301.       x_center, y_center + y, color, SOLID );
  1302.  
  1303.    /* draw top of folder (upper) */
  1304.  
  1305.    gr_line( ui_screen, x_center - x, y_center + y,
  1306.       x_center, y_center + y, color, SOLID );
  1307.  
  1308.    /* draw file tab (lower) */
  1309.  
  1310.    gr_line( ui_screen, x_center + x, y_center + y - 4,
  1311.       x_center + 4, y_center + y - 4, color, SOLID );
  1312.    gr_line( ui_screen, x_center + 4, y_center + y - 4,
  1313.       x_center, y_center + y - 2, color, SOLID );
  1314.  
  1315.    /* draw top of folder (lower) */
  1316.  
  1317.    gr_line( ui_screen, x_center - x, y_center + y - 2,
  1318.       x_center, y_center + y - 2, color, SOLID );
  1319.  
  1320. #endif
  1321.  
  1322.    }
  1323.  
  1324. /****************************************************************
  1325.  
  1326.    uii_exec()      Icon for executable files
  1327.  
  1328. ****************************************************************/
  1329.  
  1330. uii_exec( x1, y1, x2, y2, color )
  1331.    int x1, y1, x2, y2, color;
  1332.    {
  1333. #ifdef USE_ICONS
  1334.    ui_pbmcenter( ui_screen, x1, y1, x2, y2, &ui_exicon );
  1335. #else
  1336.    int x, y, y_center, x_center;
  1337.  
  1338.    /* calculate the center of the icon area */
  1339.  
  1340.    y_center = y1 + (( y2 - y1 ) / 2 );
  1341.    x_center = x1 + (( x2 - x1 ) / 2 );
  1342.  
  1343.    /* calculate appropriate sizes for the icon */
  1344.  
  1345.    y = ( y2 - y1 ) / 4;
  1346.    x = ( y * gr_pysize ) / gr_pxsize;
  1347.  
  1348.    /* draw the icon rectangle */
  1349.  
  1350.    gr_rectangle( ui_screen, x_center - x,
  1351.       y_center - y,
  1352.       x_center + x,
  1353.       y_center + y, color, HOLLOW );
  1354.  
  1355.    /* show circle to indicate executable */
  1356.  
  1357.    gr_circle( ui_screen, x_center, y_center,
  1358.       y / 3, color, GRID );
  1359.  
  1360. #endif
  1361.  
  1362.    }
  1363.  
  1364.